#include <iostream>
#include <string>
#include <map>
#include <list>
#include <algorithm>
#include <muduo/base/Atomic.h>
#include <muduo/base/Logging.h>
#include <muduo/base/Thread.h>
#include <muduo/base/ThreadPool.h>
#include <muduo/net/EventLoop.h>
#include <muduo/net/InetAddress.h>
#include <muduo/net/TcpServer.h>
#include <muduo/base/ThreadLocalSingleton.h>
#include "model/FlightChessBoardSession.h"

using namespace muduo;
using namespace muduo::net;
using namespace std;
using namespace model_flight_chess_board;

namespace control_flight_chess_board
{
	//消息的类型
	enum MSG_CMD {
		MSG_ERR = 0xffff,
		MSG_TO_SERVER  = 1,
		MSG_TO_CLIENT,//响应消息的标识
		MSG_CLIENT_LOGIN,//客户登陆和其它的收发服务区分开来
		MSG_TO_OTHER_CLIENT,//单个转发
		MSG_TO_OTHER_CLIENTS,//部分转发
		MSG_TO_ALL_CLIENTS,//全部转发
	};
	//基本的请求结构
	struct BaseConnInfoHead
	{
		uint16_t cmd;//消息的类型
		uint16_t len;//消息的长度
		uint8_t data[0];//具体的数据
	};
	//单个转发的消息头
	//加上端口判断
	struct SingleTransmitInfoHead
	{
		uint32_t d_ip;//目的ip
		uint16_t d_port;//目的端口
		uint16_t d_len;//要转发的数据长度
		uint8_t data[0];//具体的数据
	};
	//响应错误的消息头
	struct ErrInfoHead
	{
		uint32_t err_no;//错误的消息号
		uint32_t err_msg_len;//错误的消息长度
		char msg[0];//错误的消息描述
	};

	class FlightChessBoardServer
	{
	private:
		//用於記錄連接到服務器的客戶端的連接句柄
		//格式爲ip:port字符串,連接句柄
		typedef map<std::string,TcpConnectionPtr> ConnectionMap;
		//用於記錄連接到服務器的客戶端的基本信息
		//格式爲角色,基本信息json列表
		typedef map<std::string,std::list<std::string> > ConnectionBaseInfoMap;
		//用於記錄當前用戶個數的列表
		//格式爲ip:port字符串,客戶端基本信息json
		typedef map<std::string,std::string> ConnectionUserInfoMap;
		typedef ThreadLocalSingleton<FlightChessBoardSession> FcbSession;
		TcpServer server_;
		ThreadPool threadPool_;
		int numThreads_;
		Timestamp startTime_;
		ConnectionMap connections_;
		//這個結構的值存儲的就是json格式，然後按照
		//json格式來存取數據
		ConnectionBaseInfoMap connectionsInfo_;
		ConnectionUserInfoMap allconnectionsInfo_;
		const uint32_t max_buf_len = 4096;//该服务器目前运行的缓冲区最大数量
	public:
		FlightChessBoardServer(EventLoop *loop,const InetAddress &listenAddr,int numThreads);
		~FlightChessBoardServer();
		void Start();
	private:
		void OnConnection(const TcpConnectionPtr &conn);
		void OnMessage(const TcpConnectionPtr &conn,Buffer *buf,Timestamp);
		void OnWriteComplete(const TcpConnectionPtr &conn);
		static void ThreadInit();//单个线程初始化
		//该服务器用来构建错误响应的封装函数
		static void ErrResponseMsgMake(uint32_t err_no,const char *err_msg_cstr,vector<uint8_t> &dst_v);
		//用于处理每个会话的消息发送的回调
		static void FcbSessionOutputDataCallback(const TcpConnectionPtr &conn,const char *buf,size_t len);
		static void FcbSessionInputDataCallback(const vector<uint8_t> &buf);
		//用于会话错误消息发送的会调
		static void FcbSessionOutputErrMsgCallback(const TcpConnectionPtr &conn,uint32_t err_no,const char *err_msg_str);
		//用于处理每个会话的消息接收的回调
		static void FcbSessionRecvCallback(const TcpConnectionPtr &conn,const vector<uint8_t> &buf);
	};
};
